package HuginnCommunications;
use strict;
use warnings;
use HuginnConfiguration qw ( %Config );
use Net::SMTP::TLS;
use Net::SMTP::SSL;
use PDF::API2;
use feature 'state';
use feature 'say';
use File::Path;
use File::Basename;
use Data::UUID;
use MIME::Lite;

use MIME::Base64;
use File::Spec;
use LWP::MediaTypes;

use Cwd qw (chdir abs_path getcwd);
require Exporter;
our @ISA = qw(Exporter);
our @EXPORT_OK = qw( SendFax SendEmail SendSMS GnokiiGenerateConfig SendToLogFile LoadMainLoopDb LoadMainStatus send_mail_with_attachments);


our $uuid_gen = new Data::UUID;
sub SendFax
{
    my ($destination,$message) = @_;
    die "Missing destination" unless defined($destination);
    die "Missing message" unless defined($message);    
    unless( -d $Config{FAX_TMP_PATH}."/")
    {
	mkpath($Config{FAX_TMP_PATH}."/") or die "Unable to create temporary path: $!";
    }
    my $dst = $Config{FAX_TMP_PATH} . "/" . $uuid_gen->create_str();
    $dst=~s/\-/_/g;
#    my $dst_txt =$dst .".txt";
#    my $dst_tiff =$dst .".%03d";
#    my $dst_tiff1 =$dst .".001";
#    open DST_TXT, ">$dst_txt" or die "Unable to open temporary file: $!";
#    print DST_TXT "$message\n";
#    close DST_TXT;
    makePdfFile($destination,$message);
    my $cmdline = "pdf2ps $Config{FAX_TMP_PATH}/send.pdf $dst.ps";
    my $faxline = "$Config{FAX_FAX_FULLPATH} send -v -l $destination $dst.ps";
#    my $cmdline = "$Config{FAX_EFIX_FULLPATH} -n$dst_tiff $dst_txt";
#    my $faxline = "$Config{FAX_EFAX_FULLPATH} -d $Config{FAX_MODEM_DEVICE} -t T$destination $dst_tiff1";
    
#    say $cmdline;
    my $output=`$cmdline 2>&1`;
    die "Unable to prepare fax: $output" if $?;
    $output=`$faxline 2>&1`;
    die "Unable to transmit fax: $output" if $?;
}

sub SendEmail
{
    my $destination = $_[0] or die "Missing destination";
    my $body = $_[1] or die "Missing message";
    my $path_archivio = $_[2] || 0;
    my $subject = $body;
    $subject =~s/[\r\n\t]/ /g;
    
    

    if($path_archivio)
    {
        send_mail_with_attachments($destination,$subject,$body,$path_archivio);
    }
    else
    {    
        send_mail_with_attachments($destination, $subject,$body);
    }
    # my $mailer = new Net::SMTP::TLS(  
        # $Config{EMAIL_HOST},  
        # Hello   =>      $Config{EMAIL_HOST},  
        # Port    =>      $Config{EMAIL_PORT},  
        # User    =>      $Config{EMAIL_USERNAME},  
        # Password=>      $Config{EMAIL_PASSWORD});  

    
    # $mailer->mail($Config{EMAIL_USERNAME});  
    # $mailer->to($destination);
    # $mailer->data;

    # my $message = MIME::Lite->new(
        # From    => "arginiuniti\@domain.com",
        # To      => $destination,
        # Subject => "Subject: ".$subject."\n",
        # Type    => 'multipart/mixed'
    # );
#    Message body
    # $message->attach(
        # Type => "TEXT",
        # Data => $body,
    # );

    # if($path_archivio)
    # {
        # my $filepath = $path_archivio;
        # my @fileNameSplit = split(/\//, $filepath);
        # my $fCount = @fileNameSplit;
        # my $filename = $fileNameSplit[$fCount-1];
        # $message->attach(
                # Type        => "application/zip",
                # Path        => $filepath,
                # Filename    => $filename,
                # Encoding 	=> "base64",
                # Disposition => 'attachment',		
        # );
    # }
    # $mailer->datasend($message->as_string);
    # $mailer->dataend();
    # $mailer->quit();
  
#    $mailer->datasend("Subject: ".$subject."\n");  
#    $mailer->datasend($message);  
#    $mailer->dataend;  
#    $mailer->quit;
}
sub GnokiiGenerateConfig
{
    state $x = 0;
    return if $x;
    $x=1;
    print "Create configuration\n";
    open CFG,">${Config{SMS_FULL_GNOKII_CONFIG_PATH}}" or die "Unable to open config file";
    say CFG "[global]";
    say CFG "port = ${Config{SMS_MODEM_DEVICE}}";
    say CFG "model = AT";
    say CFG "connection = serial";
    close CFG;
}
sub SendSMS
{
    #GnokiiGenerateConfig;
    my $destination = $_[0] or die "Missing destination";
    my $message = $_[1] or die "Missing message";
    $message =~s/[\r\n\t]/ /g; #problema per messaggi troppo lunghi
    my $offset=0;
    my $lenght=length($message);
    my ($text,$output);
    for ($offset=0;$offset<$lenght;$offset=$offset+160)
    {
        $text=substr($message,$offset,160);
        $output.=`echo $text |  $Config{SMS_FULL_GNOKII_PATH} --config $Config{SMS_FULL_GNOKII_CONFIG_PATH} --sendsms $destination 2>&1`;    
    
    }
    die "Unable to send sms: $output" if $?;
}
sub SendToLogFile
{
    my $destination = $_[0] or die "Missing destination";
    my $message = $_[1] or die "Missing message";
    open DESTINATION, ">>$Config{LOGFILE}" or die "Unable to open file";
    print DESTINATION "Sending to $destination the following message:\n";
    print DESTINATION "\t$message\n";
    close DESTINATION;
}
sub LoadMainLoopDb
{
    my $current_dir =getcwd;
    eval
    {
	  chdir(dirname(abs_path($Config{MAIN_PHP}))) or die "Unable to chdir: $!";
	  my $message = "Start LoadMainLoopDb";
	  my $output=`php $Config{MAIN_PHP}`;
	  die "Unable to send sms: $output" if $?;

    };
    die "LoadMainLoopDb failed: $@)" if $@;
    chdir $current_dir;
}

sub makePdfFile
{
    my ($destination,$message) = @_;
    die "Missing destination" unless defined($destination);
    die "Missing message" unless defined($message);    

    # Create a blank PDF file
    my $pdf = PDF::API2->new();

    # Open an existing PDF file
    $pdf = PDF::API2->open($Config{MODELLO_PDF});

    # Retrieve an existing page
    my $page = $pdf->openpage(-1);

    # Set the page size
    $page->mediabox('A4');

    # Add a built-in font to the PDF
    my $font = $pdf->corefont('Georgia');

    # Add some text to the page
    my $altezza=650;

    my $text = $page->text();
    $text->font($font, 10);
    $text->translate(60, $altezza);
    $text->text("Destinazione: $destination");

    my @values = split(/\n/, $message);    
    $altezza=$altezza-30;
    foreach my $val (@values)
    {
        
        $text->translate(60, $altezza);
        $text->text($val);
        $altezza -=30;
    }
    # Save the PDF
    $pdf->saveas($Config{FAX_TMP_PATH}."/send.pdf");
}
sub LoadMainStatus
{
    my $current_dir =getcwd;
    eval
    {
	  chdir(dirname(abs_path($Config{MAIN_STATUS_PHP}))) or die "Unable to chdir: $!";
	  my $message = "Start LoadMainStatus";
	  my $output=`php $Config{MAIN_STATUS_PHP}`;
	  die "Unable to send sms: $output" if $?;

    };
    die "LoadMainLoopDb failed: $@)" if $@;
    chdir $current_dir;
}

sub send_mail_with_attachments 
{
     #my ($to,$subject,@bodyVal,@attachments)=@_;
     my $to = shift(@_);
     my $subject = shift(@_);
     my $body = shift(@_);
     my @attachments = @_;

     my @bodyVal = split('@', $body);

     my $from = $Config{EMAIL_FROM};
     my $password = $Config{EMAIL_PASSWORD};

     my $smtp;

     if (not $smtp = Net::SMTP::SSL->new($Config{EMAIL_HOST},
                                  Port => 465,
                                  Debug => 0)) {
         die "Could not connect to server\n";
     }

     # Authenticate
     $smtp->auth($from, $password)
         || die "Authentication failed!\n";

     # Create arbitrary boundary text used to seperate
     # different parts of the message
     my ($bi, $bn, @bchrs);
     my $boundry = "";
     foreach $bn (48..57,65..90,97..122) {
         $bchrs[$bi++] = chr($bn);
     }
     foreach $bn (0..20) {
         $boundry .= $bchrs[rand($bi)];
     }

     # Send the header
     $smtp->mail($from . "\n");
     my @recepients = split(/,/, $to);
     foreach my $recp (@recepients) {
         $smtp->to($recp . "\n");
     }
     $smtp->data();
     $smtp->datasend("From: " . $from . "\n");
     $smtp->datasend("To: " . $to . "\n");
     $smtp->datasend("Subject: " . $subject . "\n");
     $smtp->datasend("MIME-Version: 1.0\n");
     $smtp->datasend("Content-Type: multipart/mixed; BOUNDARY=\"$boundry\"\n");

     # Send the body
     $smtp->datasend("\n--$boundry\n");
     $smtp->datasend("Content-Type: text/plain\n");
    
     foreach my $body (@bodyVal)
     {
        $smtp->datasend($body . "\n\n");
     }
 
     # Send attachments
     foreach my $file (@attachments) {
         unless (-f $file) {
             die "Unable to find attachment file $file\n";
             next;
         }
         my($bytesread, $buffer, $data, $total);
         open(FH, "$file") || die "Failed to open $file\n";
         binmode(FH);
         while (($bytesread = sysread(FH, $buffer, 1024)) == 1024) {
             $total += $bytesread;
             $data .= $buffer;
         }
         if ($bytesread) {
             $data .= $buffer;
             $total += $bytesread;
         }
         close FH;

         # Get the file name without its directory
         my ($volume, $dir, $fileName) = File::Spec->splitpath($file);

         # Try and guess the MIME type from the file extension so
         # that the email client doesn't have to
         my $contentType = guess_media_type($file);

         if ($data) {
             $smtp->datasend("--$boundry\n");
             $smtp->datasend("Content-Type: $contentType; name=\"$fileName\"\n");
             $smtp->datasend("Content-Transfer-Encoding: base64\n");
             $smtp->datasend("Content-Disposition: attachment; =filename=\"$fileName\"\n\n");
             $smtp->datasend(encode_base64($data));
             $smtp->datasend("--$boundry\n");
         }
     }

     # Quit
     $smtp->datasend("\n--$boundry--\n"); # send boundary end message
     $smtp->datasend("\n");
     $smtp->dataend();
     $smtp->quit;
}
1;
